#ifndef _GAME_BRAIN_H_
#define _GAME_BRAIN_H_
#include "game_platform.h"
enum brain_type {
    Type_brain_hero,
    Type_brain_snake,
    Type_brain_familiar,
    Type_brain_floaty_thing_for_now,
    Type_brain_monster,
    Type_brain_count,
};

struct brain_slot {
    uint16 Type;
    uint16 Index;
};

struct brain_id {
    uint32 Value;
};
struct entity;
struct brain_hero {
    entity* Body;
    entity* Head;
    entity* Glove;
};
struct brain_monster {
    entity* Body;
};
struct brain_snake {
    entity* Segments[16];
};
struct brain_familiar {
    entity* Head;
};
struct brain {
    brain_id ID;
    brain_type Type;
    union {
        brain_hero Hero;
        brain_monster Monster;
        brain_familiar Familiar;
        brain_snake Snake;
        entity* Array;
    };
};
#define BrainSlotFor(type, member) \
    BrainSlotFor_(Type_##type, offsetof(type, member) / sizeof(entity*))
#define IndexedBrainSlotFor(type, member, index) \
    BrainSlotFor_(Type_##type, (offsetof(type, member) / sizeof(entity*)) + (index))
inline brain_slot BrainSlotFor_(brain_type Type, uint16 PackValue) {
    brain_slot Result = {(uint16)Type, PackValue};
    return Result;
}
enum reserved_brain_id {
    ReservedBrainID_FirstHero = 1,
    ReservedBrainID_LastHero = (ReservedBrainID_FirstHero + MAX_CONTROLLER_COUNT - 1),
    ReservedBrainID_FirstFree,
};

struct brain_hash {
    brain* Ptr;
    brain_id ID;
};

inline brain_id NoBrain(void) {
    brain_id Result = {};
    return Result;
}
inline bool32 IsType(brain_slot Slot, brain_type Type) {  //
    bool32 Result = ((Slot.Index != 0) && (Slot.Type == Type));
    return Result;
}
#define MAX_BRAIN_SLOT_COUNT ((sizeof(brain) - OffsetOf(brain, Array)) / sizeof(entity*))
void MarkBrainActives(brain* Brain);
inline entity* GetEntityInSlot(brain* Brain, uint32 SlotIndex) {
    Assert(SlotIndex < MAX_BRAIN_SLOT_COUNT);
    entity* Result = (&Brain->Array)[SlotIndex];
    return Result;
}
#endif